<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>大文件下载管理器</title>
    <style>
        :root {
            --primary: #2196F3;
            --success: #4CAF50;
            --error: #f44336;
        }

        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }

        body {
            font-family: 'Segoe UI', system-ui, sans-serif;
            background: #f0f2f5;
            padding: 2rem;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.05);
        }

        .file-list {
            padding: 1.5rem;
        }

        .file-item {
            display: flex;
            align-items: center;
            padding: 1rem;
            margin-bottom: 1rem;
            background: #f8f9fa;
            border-radius: 8px;
            transition: transform 0.2s;
        }

        .file-item:hover {
            transform: translateY(-2px);
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
        }

        .file-info {
            flex: 1;
            margin-right: 1.5rem;
        }

        .file-name {
            font-weight: 600;
            color: #1a1a1a;
            margin-bottom: 0.25rem;
        }

        .file-meta {
            display: flex;
            gap: 1.5rem;
            color: #666;
            font-size: 0.9em;
        }

        .download-btn {
            background: var(--primary);
            color: white;
            border: none;
            padding: 0.75rem 1.5rem;
            border-radius: 6px;
            cursor: pointer;
            transition: all 0.2s;
            display: flex;
            align-items: center;
            gap: 0.5rem;
            font-weight: 500;
        }

        .download-btn:disabled {
            opacity: 0.7;
            cursor: not-allowed;
        }

        .download-btn:hover:not(:disabled) {
            filter: brightness(1.1);
        }

        .progress-panel {
            padding: 1.5rem;
            border-top: 1px solid #eee;
        }

        .progress-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 1rem;
        }

        .progress-bar {
            height: 10px;
            background: #eee;
            border-radius: 5px;
            overflow: hidden;
            position: relative;
        }

        /* 新增漂浮进度面板样式 */
        .download-floating-panel {
            position: fixed;
            top: 20px;
            right: 20px;
            width: 500px;
            background: white;
            border-radius: 12px;
            box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            z-index: 1000;
            padding: 1.5rem;
            display: none;
        }

        /* 调整容器间距 */
        .container {
            margin-top: 80px; /* 为漂浮面板留出空间 */
        }

        .progress-fill {
            height: 100%;
            background: var(--success);
            transition: width 0.5s cubic-bezier(0.4, 0, 0.2, 1);
            width: 0;
        }

        .stats {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 1.5rem;
            margin-top: 1.5rem;
        }

        .stat-item {
            background: #f8f9fa;
            padding: 1rem;
            border-radius: 8px;
            text-align: center;
        }

        .stat-label {
            color: #666;
            font-size: 0.9em;
            margin-bottom: 0.5rem;
        }

        .stat-value {
            font-weight: 600;
            color: #333;
        }

        .error-message {
            position: fixed;
            bottom: 1.5rem;
            right: 1.5rem;
            background: var(--error);
            color: white;
            padding: 1rem 2rem;
            border-radius: 8px;
            display: flex;
            align-items: center;
            gap: 1rem;
            animation: slideIn 0.3s ease;
            box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
        }

        @keyframes slideIn {
            from { transform: translateX(100%); }
            to { transform: translateX(0); }
        }

        @media (max-width: 768px) {
            body {
                padding: 1rem;
            }

            .file-item {
                flex-direction: column;
                align-items: flex-start;
            }

            .download-btn {
                width: 100%;
                margin-top: 1rem;
            }

            .stats {
                grid-template-columns: 1fr;
            }
        }

        .speed-indicator {
            animation: pulse 1.5s infinite;
        }

        .file-table {
            width: 100%;
            border-collapse: collapse;
            margin-bottom: 20px;
        }

        .file-table th, .file-table td {
            border: 1px solid #ebeef5;
            padding: 12px;
            text-align: left;
        }

        .file-table th {
            background-color: #f5f7fa;
            color: #909399;
        }

        .el-button {
            color: #fff;
            background-color: #98FB98;
            border: none;
            padding: 10px 12px;
            margin-left:5px;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }

        .el-button:hover {
            background-color: #66b1ff;
        }

        .dialog-mask {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0,0,0,.5);
            display: none;
        }

        .dialog-wrapper {
            position: fixed;
            top: 15vh;
            left: 50%;
            transform: translateX(-50%);
            background: white;
            border-radius: 4px;
            box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
            width: 70%;
            min-width: 400px;
            display: none;
        }

        .dialog-header {
            padding: 20px;
            border-bottom: 1px solid #ebeef5;
            font-size: 18px;
            color: #303133;
        }

        .dialog-body {
            padding: 20px;
            max-height: 70vh;
            overflow: auto;
        }

        .loading {
            text-align: center;
            padding: 40px 0;
            color: #409eff;
        }

        .text-preview {
            white-space: pre-wrap;
            background: #f8f8f8;
            padding: 10px;
            border-radius: 4px;
            font-family: monospace;
        }

        .el-table {
            width: 100%;
            border-collapse: collapse;
        }

        .el-table td {
            border: 1px solid #ebeef5;
            padding: 12px;
        }

        .error-message {
            color: #f56c6c;
            padding: 10px;
            background: #fef0f0;
            border-radius: 4px;
        }

        /* 消息容器定位 */
        .message-container {
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 9999;
            max-width: 400px;
        }

        /* 基础消息样式 */
        .message {
            position: relative;
            padding: 12px 40px 12px 20px;
            margin-bottom: 12px;
            border-radius: 4px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            background: #fff;
            border: 1px solid #ebeef5;
            transition: all 0.3s;
            opacity: 0;
            transform: translateX(100%);
            display: flex;
            align-items: center;
        }

        /* 进场动画 */
        .message.show {
            opacity: 1;
            transform: translateX(0);
        }

        /* 不同类型颜色 */
        .message.success {
            border-color: #e1f3d8;
            background: #f0f9eb;
            color: #67c23a;
        }

        .message.error {
            border-color: #fde2e2;
            background: #fef0f0;
            color: #f56c6c;
        }

        .message.warning {
            border-color: #faecd8;
            background: #fdf6ec;
            color: #e6a23c;
        }

        .message.info {
            border-color: #ebeef5;
            background: #edf2fc;
            color: #909399;
        }

        /* 关闭按钮 */
        .message-close {
            position: absolute;
            right: 16px;
            top: 50%;
            transform: translateY(-50%);
            cursor: pointer;
            color: currentColor;
            opacity: 0.6;
            font-size: 16px;
            line-height: 1;
        }

        .message-close:hover {
            opacity: 1;
        }

        /* 图标样式 */
        .message-icon {
            margin-right: 10px;
            font-size: 18px;
        }

        @keyframes pulse {
            0% { opacity: 1; }
            50% { opacity: 0.5; }
            100% { opacity: 1; }
        }
    </style>
</head>
<body>
    <!-- 新增搜索框 -->
    <div class="container">
        <div style="margin-bottom: 1rem;">
            <input type="text" id="searchInput" placeholder="搜索文件..." oninput="filterFiles()" style="width: 100%; padding: 0.75rem; border: 1px solid #ccc; border-radius: 6px;">
        </div>
        <div class="file-list" id="fileList">
            <!-- 文件列表动态加载 -->
        </div>
        <div class="progress-panel" id="progressPanel" style="display: none;">
            <div class="progress-header">
                <h3>正在下载 <span id="currentFileName"></span></h3>
                <button class="download-btn" onclick="cancelDownload()" style="background: var(--error)">
                    取消下载
                </button>
            </div>
            <div class="progress-bar">
                <div class="progress-fill" id="progressFill"></div>
            </div>
            <div class="stats" id="stats"></div>
        </div>
    </div>

    <!-- 弹窗遮罩 -->
    <div class="dialog-mask" id="dialogMask"></div>

    <!-- 预览弹窗 -->
    <div class="dialog-wrapper" id="previewDialog">
        <div class="dialog-header" id="previewTitle"></div>
        <div class="dialog-body" id="previewContent">
            <!-- 内容动态加载 -->
        </div>
    </div>
    <script>
        // 下载状态管理
        let downloadState = {
            controller: null,
            fileHandle: null,
            writableStream: null,
            startTime: null,
            receivedBytes: 0,
            totalBytes: 0,
            lastUpdateTime: null,
            lastBytes: 0,
            updateInterval: null
        };

        // 初始化文件列表
        window.addEventListener('DOMContentLoaded', async () => {
            try {
                const response = await fetch('/api/files');
                const { code, data, error } = await response.json();

                if (code === 200) {
                    renderFileList(data);
                } else {
                    showError(error || '获取文件列表失败');
                }
            } catch (err) {
                showError('网络连接异常');
            }
        });

        // 渲染文件列表
        function renderFileList(files) {
            const container = document.getElementById('fileList');
            container.innerHTML = files.map(file =>
               ` <div class="file-item">
                    <div class="file-info">
                        <div class="file-name">${file.name}</div>
                        <div class="file-meta">
                            <span>大小: ${formatSize(file.size)}</span>
                            <span>修改: ${formatDate(file.modified)}</span>
                        </div>
                    </div>
                    <button class="download-btn"
                        onclick="startDownload('${encodeURIComponent(file.name)}', ${file.size})">
                        下载文件
                    </button>
                    <button class="el-button"
                            onclick="previewFile('${file.name}')">预览</button>
                </div>`
            ).join('');
        }

        // 开始下载
        async function startDownload(encodedFilename, fileSize) {
            try {
                // 初始化下载状态
                downloadState = {
                    controller: new AbortController(),
                    fileHandle: null,
                    writableStream: null,
                    startTime: Date.now(),
                    receivedBytes: 0,
                    totalBytes: fileSize,
                    lastUpdateTime: Date.now(),
                    lastBytes: 0,
                    updateInterval: setInterval(updateStats, 1000)
                };

                // 显示下载面板
                document.getElementById('progressPanel').style.display = 'block';
                document.getElementById('currentFileName').textContent = decodeURIComponent(encodedFilename);
                document.getElementById('progressFill').style.background = 'var(--success)';
                // 显示漂浮面板
                const floatingPanel = document.getElementById('floatingPanel');
                floatingPanel.style.display = 'block';
                document.getElementById('floatingFileName').textContent = decodeURIComponent(encodedFilename);
                document.getElementById('floatingProgress').style.background = 'var(--success)';

                // 请求保存位置
                downloadState.fileHandle = await window.showSaveFilePicker({
                    suggestedName: decodeURIComponent(encodedFilename)
                });

                // 创建可写流
                downloadState.writableStream = await downloadState.fileHandle.createWritable();

                // 启动下载请求
                const response = await fetch(`/api/download?file=${encodedFilename}`, {
                    signal: downloadState.controller.signal
                });

                if (!response.ok) throw new Error('HTTP错误: ${response.status}');
                if (!response.body) throw new Error('无效的响应体');

                // 读取数据流
                const reader = response.body.getReader();
                while (true) {
                    const { done, value } = await reader.read();
                    if (done) break;

                    await downloadState.writableStream.write(value);
                    downloadState.receivedBytes += value.length;
                    updateProgress();
                }

                // 完成下载
                await downloadState.writableStream.close();
                downloadComplete();
            } catch (err) {
                handleDownloadError(err);
            } finally {
                cleanupDownload();
            }
        }

        // 修改后的进度更新函数
        function updateProgress() {
            const progress = (downloadState.receivedBytes / downloadState.totalBytes * 100).toFixed(1);
            document.getElementById('floatingProgress').style.width = `${progress}%`;
        }

        // 更新统计信息
        function updateStats() {
            const now = Date.now();
            const timeDelta = (now - downloadState.lastUpdateTime) / 1000;
            const bytesDelta = downloadState.receivedBytes - downloadState.lastBytes;

            // 计算实时速度
            const speed = bytesDelta / (timeDelta * 1024 * 1024); // MB/s
            const formattedSpeed = isFinite(speed) ? speed.toFixed(2) : 0;

            // 计算剩余时间
            const remainingBytes = downloadState.totalBytes - downloadState.receivedBytes;
            const remainingTime = speed > 0 ? remainingBytes / (speed * 1024 * 1024) : Infinity;

            // 更新显示
            document.getElementById('stats').innerHTML =
                `<div class="stat-item">
                    <div class="stat-label">下载速度</div>
                    <div class="stat-value">
                        <span class="speed-indicator">${formattedSpeed}</span> MB/s
                    </div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">剩余时间</div>
                    <div class="stat-value">${formatTime(remainingTime)}</div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">已传输</div>
                    <div class="stat-value">${formatSize(downloadState.receivedBytes)}</div>
                </div>`
            ;

            // 更新记录
            downloadState.lastUpdateTime = now;
            downloadState.lastBytes = downloadState.receivedBytes;
            // 更新漂浮面板统计
            document.getElementById('floatingStats').innerHTML = `
                <div class="stat-item">
                    <div class="stat-label">速度</div>
                    <div class="stat-value">${formattedSpeed} MB/s</div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">剩余时间</div>
                    <div class="stat-value">${formatTime(remainingTime)}</div>
                </div>
                <div class="stat-item">
                    <div class="stat-label">已下载</div>
                    <div class="stat-value">${formatSize(downloadState.receivedBytes)}</div>
                </div>`
            ;
        }

        // 取消下载
        function cancelDownload() {
            if (downloadState.controller) {
                // 1. 终止下载请求
                downloadState.controller.abort();

                // 2. 关闭文件写入流
                if (downloadState.writableStream) {
                    downloadState.writableStream.close().catch(() => {});
                }

                // 3. 清理状态
                cleanupDownload();

                // 4. 更新UI
                showError('下载已取消');
                document.getElementById('progressFill').style.background = 'var(--error)';

                // 5. 3秒后隐藏面板
                setTimeout(() => {
                    document.getElementById('progressPanel').style.display = 'none';
                }, 3000);
                // 立即隐藏漂浮面板
                document.getElementById('floatingPanel').style.display = 'none';
            }
        }

        // 下载完成处理
        function downloadComplete() {
            showMessage('下载完成', 'success');
            setTimeout(() => {
                document.getElementById('progressPanel').style.display = 'none';
                document.getElementById('progressFill').style.width = '0%';
            }, 2000);
        }

        // 修改后的错误处理
        function handleDownloadError(err) {
            if (err.name !== 'AbortError') {
                showError(err.message || '下载失败');
                document.getElementById('progressFill').style.background = 'var(--error)';
            }

            // 无论何种错误都执行清理
            cleanupDownload();
        }

        // 增强的清理函数
        function cleanupDownload() {
            // 清除定时器
            clearInterval(downloadState.updateInterval);

            // 释放资源
            if (downloadState.controller) {
                downloadState.controller = null;
            }
            if (downloadState.fileHandle) {
                downloadState.fileHandle = null;
            }

            // 重置进度条
            document.getElementById('progressFill').style.width = '0%';

            // 重置统计信息
            document.getElementById('stats').innerHTML = '';

            // 重置下载状态对象
            downloadState = {
                controller: null,
                fileHandle: null,
                writableStream: null,
                startTime: null,
                receivedBytes: 0,
                totalBytes: 0,
                lastUpdateTime: null,
                lastBytes: 0,
                updateInterval: null
            };
            // 隐藏漂浮面板
            document.getElementById('floatingPanel').style.display = 'none';
            document.getElementById('floatingProgress').style.width = '0%';
        }

        // 辅助函数：格式化文件大小
        function formatSize(bytes) {
            const units = ['B', 'KB', 'MB', 'GB'];
            let unitIndex = 0;

            while (bytes >= 1024 && unitIndex < units.length - 1) {
                bytes /= 1024;
                unitIndex++;
            }

            return `${bytes.toFixed(2)} ${units[unitIndex]}`;
        }

        // 辅助函数：格式化时间戳
        function formatDate(timestamp) {
            const date = new Date(timestamp * 1000);
            return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
        }

        // 辅助函数：格式化剩余时间
        function formatTime(seconds) {
            if (!isFinite(seconds) || seconds <= 0) return '--';
            const mins = Math.floor(seconds / 60);
            const secs = Math.floor(seconds % 60);
            return `${mins.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        }

        // 显示提示消息
        // 消息队列管理
        let messageQueue = [];

        function showMessage(message, type = 'success', duration = 3000) {
            // 创建容器（如果不存在）
            let container = document.querySelector('.message-container');
            if (!container) {
                container = document.createElement('div');
                container.className = 'message-container';
                document.body.appendChild(container);
            }

            // 创建消息元素
            const messageEl = document.createElement('div');
            messageEl.className = `message ${type}`;

            // 添加图标（可替换为字体图标）
            const icons = {
                success: '✓',
                error: '✕',
                warning: '⚠',
                info: 'ⓘ'
            };
            messageEl.innerHTML = `
                <span class="message-icon">${icons[type]}</span>
                <span>${message}</span>
                <span class="message-close">×</span>
            `;

            // 添加到容器
            container.appendChild(messageEl);

            // 触发进场动画
            setTimeout(() => messageEl.classList.add('show'), 10);

            // 自动关闭
            let timer;
            const close = () => {
                messageEl.classList.remove('show');
                setTimeout(() => {
                    messageEl.remove();
                    if (container.children.length === 0) {
                        container.remove();
                    }
                }, 300);
            };

            timer = setTimeout(close, duration);

            // 悬停暂停
            messageEl.addEventListener('mouseenter', () => clearTimeout(timer));
            messageEl.addEventListener('mouseleave', () => {
                timer = setTimeout(close, duration);
            });

            timer = setTimeout(close, duration);

            // 关闭按钮事件
            messageEl.querySelector('.message-close').addEventListener('click', close);
        }

        // 显示错误消息
        function showError(message) {
            const elem = document.createElement('div');
            elem.className = 'error-message';
            elem.innerHTML = `
                ${message}
                <button onclick="this.parentElement.remove()">×</button>`
            ;
            document.body.appendChild(elem);
            setTimeout(() => elem.remove(), 5000);
        }

        // 显示弹窗
        function showDialog() {
            document.getElementById('dialogMask').style.display = 'block';
            document.getElementById('previewDialog').style.display = 'block';
        }

        // 隐藏弹窗
        function hideDialog() {
            document.getElementById('dialogMask').style.display = 'none';
            document.getElementById('previewDialog').style.display = 'none';
            document.getElementById('previewContent').innerHTML = '';
        }

        // 文件预览逻辑
        async function previewFile(filename) {
            showDialog();
            document.getElementById('previewTitle').textContent = `预览文件 - ${filename}`;

            // 显示加载状态
            const contentDiv = document.getElementById('previewContent');
            contentDiv.innerHTML = '<div class="loading">加载中...</div>';

            try {
                const response = await fetch(`/api/preview?file=${encodeURIComponent(filename)}`);

                // 根据 Content-Type 判断数据类型
                const contentType = response.headers.get('Content-Type');

                if (contentType && contentType.includes('application/json')) {
                    // 处理 JSON 响应
                    const result = await response.json();

                    if (result.code === 200) {
                        handlePreviewContent(result, filename);
                    } else {
                        showError(result.error || '未知错误');
                    }
                } else {
                    // 处理二进制响应（图片/PDF等）
                    const result = await response.blob();
                    if (result.size > 0) {
                        handlePreviewContent(result, filename);
                    } else {
                        showError(result.error || '未知错误');
                    }
                }
            } catch (error) {
                showError(`请求失败: ${error.message}`);
            }
        }

        // 处理预览内容
        function handlePreviewContent(result, filename) {
            const contentDiv = document.getElementById('previewContent');

            if (result.type === 'text') {
                contentDiv.innerHTML = `<pre class="text-preview">${result.data}</pre>`;
            } else if (result.type === 'excel') {
                createExcelTable(result.data);
            } else if (result.type === 'html') {
                contentDiv.textContent = result.data; // 使用 textContent 来显示原始文本
            } else if (filename.toLowerCase().endsWith('.pdf')) {
                contentDiv.innerHTML = `
                    <embed src="/api/preview?file=${encodeURIComponent(filename)}"
                           type="application/pdf"
                           style="width:100%; height:70vh;">
                `;
            } else if (filename.match(/\.(png|jpg|jpeg|gif)$/i)) {
                // 修改: 处理图片的二进制返回
                fetch(`/api/preview?file=${encodeURIComponent(filename)}`, { responseType: 'blob' })
                    .then(response => response.blob())
                    .then(blob => {
                        const url = URL.createObjectURL(blob);
                        contentDiv.innerHTML = `
                            <img src="${url}"
                                 style="max-width:100%; max-height:70vh; display:block; margin:0 auto;">
                        `;
                    })
                    .catch(error => {
                        showError(`无法预览文件: ${error.message}`);
                    });
            } else if (filename.toLowerCase().endsWith('.docx')) {
                contentDiv.innerHTML = `
                    <iframe src="/api/preview?file=${encodeURIComponent(filename)}"
                            style="width:100%; height:70vh; border:none;">
                    </iframe>
                `;
            } else {
                fetch(`/api/preview?file=${encodeURIComponent(filename)}`, { responseType: 'blob' })
                    .then(response => response.blob())
                    .then(blob => {
                        const url = URL.createObjectURL(blob);
                        contentDiv.innerHTML = `
                            <embed src="${url}"
                                   type="${getMimeType(filename)}"
                                   style="width:100%; height:70vh;">
                        `;
                    })
                    .catch(error => {
                        showError(`无法预览文件: ${error.message}`);
                    });
            }
        }

        function getMimeType(filename) {
            const extension = filename.split('.').pop().toLowerCase();
            switch (extension) {
                case 'pdf':
                    return 'application/pdf';
                case 'png':
                case 'jpg':
                case 'jpeg':
                case 'gif':
                    return `image/${extension}`;
                case 'docx':
                    return 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                default:
                    return 'application/octet-stream';
            }
        }

        // 创建 Excel 表格
        function createExcelTable(data) {
            const contentDiv = document.getElementById('previewContent');
            if (data.length === 0) {
                contentDiv.innerHTML = '<div class="error-message">空文件</div>';
                return;
            }

            const table = document.createElement('table');
            table.className = 'el-table';

            // 创建表头
            const thead = document.createElement('thead');
            const headerRow = document.createElement('tr');
            Object.keys(data[0]).forEach(key => {
                const th = document.createElement('th');
                th.textContent = key;
                headerRow.appendChild(th);
            });
            thead.appendChild(headerRow);
            table.appendChild(thead);

            // 创建表格内容
            const tbody = document.createElement('tbody');
            data.forEach(row => {
                const tr = document.createElement('tr');
                Object.values(row).forEach(value => {
                    const td = document.createElement('td');
                    td.textContent = value;
                    tr.appendChild(td);
                });
                tbody.appendChild(tr);
            });
            table.appendChild(tbody);

            contentDiv.innerHTML = '';
            contentDiv.appendChild(table);
        }

        // 显示错误信息
        function showError(message) {
            const contentDiv = document.getElementById('previewContent');
            contentDiv.innerHTML = `
                <div class="error-message">
                    <span style="color: #f56c6c;">错误：</span>
                    ${message}
                </div>
            `;
        }

        // 绑定遮罩点击事件
        document.getElementById('dialogMask').addEventListener('click', hideDialog);

        // 新增文件过滤函数
        function filterFiles() {
            const input = document.getElementById('searchInput').value.toLowerCase();
            const files = document.querySelectorAll('.file-item');

            files.forEach(file => {
                const fileName = file.querySelector('.file-name').textContent.toLowerCase();
                if (fileName.includes(input)) {
                    file.style.display = '';
                } else {
                    file.style.display = 'none';
                }
            });
        }

        // 处理文件上传
        function handleFileUpload() {
            const fileInput = document.getElementById('fileInput');
            const file = fileInput.files[0];

            if (file) {
                const formData = new FormData();
                formData.append('file', file);

                fetch('/upload', {
                    method: 'POST',
                    body: formData
                })
                .then(response => response.json())
                .then(data => {
                    if (data.message === 'File uploaded successfully') {
                        showMessage(data.message, 'success');
                        // 刷新文件列表
                        refreshFileList();
                    } else {
                        showError(data.error);
                    }
                })
                .catch(error => {
                    showError('上传失败: ' + error.message);
                });
            }
        }

        // 新增文件列表刷新函数
        function refreshFileList() {
            fetch('/api/files')
                .then(response => response.json())
                .then(data => {
                    if (data.code === 200) {
                        renderFileList(data.data);
                    } else {
                        showError(data.error || '获取文件列表失败');
                    }
                })
                .catch(err => {
                    showError('网络连接异常');
                });
        }
    </script>
</body>
</html>